﻿#pragma once

#include "../argument/box_argument.hh"
#include <string>
#include <list>

namespace kratos {
namespace argument {

/**
 * 命令行参数实现类
 */
class BoxArgumentImpl : public BoxArgument {
  std::string config_file_path_{BoxArgument::DEFAULT_CONFIG_FILE_NAME}; ///< 配置文件路径
  std::string help_string_;                     ///< 帮助信息
  std::string command_;                         ///< 启动命令
  std::string host_;                            ///< 远程服务容器地址
  std::string service_name_;                    ///< 服务名称
  std::string config_center_api_;               ///< 配置中心API
  std::string proxy_host_;                      ///< 需要连接的代理, 直连代理，通过代理与其他容器通信
  bool        is_print_help_{false};            ///< 是否打印帮助
  bool        is_dump_heap_{false};             ///< 是否退出是输出分配器内未释放的对象
  bool        is_daemon_{false};                ///< 是否以守护进程方式启动
  bool        is_open_system_exception_{false}; ///< 是否捕获系统异常
  bool        is_proxy_{false};                 ///< 是否是对外的代理
  int         max_frame_{ 50 };                 ///< 最大帧率

public:
  /**
   * 构造 
   */
  BoxArgumentImpl();
  /**
   * 析构
   */
  virtual ~BoxArgumentImpl();
  /** 
   * 解析命令参数
   * 
   * \param argc 参数个数
   * \param argv 参数数组
   * \retval true 成功
   * \retval false 失败
   */
  auto parse(int argc, const char **argv) -> bool;
  /**
   * 取得配置文件路径.
   *
   * \return 配置文件路径
   */
  virtual auto get_config_file_path() const noexcept
    -> const std::string & override;
  /**
   * 获取配置文件名
   *
   * \return 配置文件名
   */
  virtual auto get_config_file_name() const noexcept -> std::string override;
  /**
   * 获取最大帧率(帧/秒).
   *
   * \return 最大帧率(帧/秒)
   */
  virtual auto get_max_frame() const noexcept -> int override;
  /**
   * 是否打印help.
   *
   * \return true或者false
   */
  virtual auto is_print_help() const noexcept -> bool override;
  /**
   * 获取帮助信息.
   *
   * \return 帮助信息
   */
  virtual auto get_help_string() const noexcept -> std::string override;
  /**
   * 获取命令.
   *
   * 当以客户端模式启动时，返回需要发送给服务容器的命令
   *
   * \return 命令
   */
  virtual auto get_command() const noexcept -> const std::string & override;
  /**
   * 获取远程服务容器地址
   *
   * 当以客户端模式启动时，需要连接的服务容器地址
   *
   * \return 远程服务容器地址
   */
  virtual auto get_host() const noexcept -> const std::string & override;
  /**
   * 是否以daemon方式启动
   *
   * 当运行在Linux操作系统时，可以已daemon方式启动
   *
   * \return true或false
   */
  virtual auto is_daemon() const noexcept -> bool override;
  /**
   * 获取服务名，废弃
   */
  virtual auto get_service_name() const noexcept
      -> const std::string & override;
  /**
   * 获取配置中心地址.
   * 
   * \return 配置中心地址
   */
  virtual auto get_config_center_api_url() const noexcept
      -> const std::string & override;
  /**
   * 是否开启系统异常捕获.
   * 
   * \return 
   */
  virtual auto is_open_system_exception() const noexcept -> bool override;
  /**
   * 是否以代理模式启动.
   * 
   * \return 
   */
  virtual auto is_proxy() const noexcept -> bool override;
  /**
   * 获取代理地址.
   * 
   * \return 
   */
  virtual auto get_proxy_host() const noexcept -> std::string override;

public:
  /**
   * 是否退出是输出分配器内未释放的对象
   */
  auto is_dump_heap() const noexcept -> bool;
  /**
   * 获取logo.
   * 
   * \return 
   */
  static auto get_logo() noexcept -> const char*;
  /**
   * 改变命令行设置的属性
   * \param command 命令
   * \return 执行结果
   */
  auto on_change(const std::string& command, std::string& result) const -> bool;

  /**
   * 设置最大帧率  
   */
  auto set_max_frame(int max_frame) const noexcept -> void;

private:
  /**
   * 解析客户端命令参数.
   * \param argc 参数个数
   * \param argv 参数数组
   * \retval true 成功
   * \retval false 失败
   */
  auto parse_as_client(int argc, const char **argv) -> bool;
  /**
   * 解析容器命令参数.
   * \param argc 参数个数
   * \param argv 参数数组
   * \retval true 成功
   * \retval false 失败
   */
  auto parse_as_server(int argc, const char **argv) -> bool;
};

} // namespace argument
} // namespace kratos
